using Microsoft.Extensions.Logging;
using System.Transactions;
using RBAC.Domain.RBAC;

namespace RBAC.Interstructrue.Base
{
    /// <summary>
    /// 角色仓储实现类
    /// </summary>
    public class RoleRepository : BaseRepository<RoleModel>, IRoleRepository
    {
        private readonly IBaseRepository<RolePermissionModel> _rolePermissionRepository;
        private readonly IBaseRepository<UserRoleModel> _userRoleRepository;

        public RoleRepository(
            IDbConnectionFactory connectionFactory, 
            IBaseRepository<RolePermissionModel> rolePermissionRepository,
            IBaseRepository<UserRoleModel> userRoleRepository,
            RBACDbContext? dbContext = null, 
            ILogger<BaseRepository<RoleModel>> logger = null) 
            : base(connectionFactory, dbContext, logger)
        {
            _rolePermissionRepository = rolePermissionRepository;
            _userRoleRepository = userRoleRepository;
        }

        /// <summary>
        /// 创建角色及其权限关联（事务操作）
        /// </summary>
        /// <param name="role">角色信息</param>
        /// <param name="permissionIds">权限ID列表</param>
        /// <returns>角色ID</returns>
        public int CreateRoleWithPermissions(RoleModel role, List<long>? permissionIds)
        {
            using var tran = new TransactionScope();
            try
            {
                // 1. 创建角色
                var roleId = Create(role);
                
                // 2. 批量创建角色权限关联
                if (permissionIds != null && permissionIds.Any())
                {
                    var rolePermissions = permissionIds.Select(permissionId => new RolePermissionModel
                    {
                        RoleId = roleId,
                        PermissionId = permissionId,
                        IsDeleted = false,
                        CreateTime = DateTime.Now
                    }).ToList();
                    
                    var batchResult = _rolePermissionRepository.CreateBatch(rolePermissions);
                    
                    if (batchResult != rolePermissions.Count)
                    {
                        throw new InvalidOperationException($"批量创建角色权限关联失败: 预期 {rolePermissions.Count} 条，实际创建 {batchResult} 条");
                    }
                }
                
                tran.Complete();
                return roleId;
            }
            catch
            {
                // 事务会自动回滚
                throw;
            }
        }

        /// <summary>
        /// 更新角色及其权限关联（事务操作）
        /// </summary>
        /// <param name="role">角色信息</param>
        /// <param name="permissionIds">权限ID列表</param>
        /// <returns>影响的行数</returns>
        public int UpdateRoleWithPermissions(RoleModel role, List<long>? permissionIds)
        {
            using var tran = new TransactionScope();
            try
            {
                // 1. 软删除现有的角色权限关联
                var existingRolePermissions = _rolePermissionRepository.GetAll("RoleId = @RoleId AND IsDeleted = false", new { RoleId = role.Id });
                
                foreach (var rolePermission in existingRolePermissions)
                {
                    rolePermission.IsDeleted = true;
                    _rolePermissionRepository.Update(rolePermission);
                }
                
                // 2. 更新角色基本信息
                var updateResult = Update(role);
                
                // 3. 创建新的角色权限关联
                if (permissionIds != null && permissionIds.Any())
                {
                    var rolePermissions = permissionIds.Select(permissionId => new RolePermissionModel
                    {
                        RoleId = role.Id,
                        PermissionId = permissionId,
                        IsDeleted = false,
                        CreateTime = DateTime.Now
                    }).ToList();
                    
                    var batchResult = _rolePermissionRepository.CreateBatch(rolePermissions);
                    
                    if (batchResult != rolePermissions.Count)
                    {
                        throw new InvalidOperationException($"批量创建角色权限关联失败: 预期 {rolePermissions.Count} 条，实际创建 {batchResult} 条");
                    }
                }
                
                tran.Complete();
                return updateResult;
            }
            catch
            {
                // 事务会自动回滚
                throw;
            }
        }

        /// <summary>
        /// 删除角色及其所有关联（事务操作）
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <returns>影响的行数</returns>
        public int DeleteRoleWithAllRelations(long roleId)
        {
            using var tran = new TransactionScope();
            try
            {
                // 1. 软删除角色权限关联
                var rolePermissions = _rolePermissionRepository.GetAll("RoleId = @RoleId AND IsDeleted = false", new { RoleId = roleId });
                
                foreach (var rolePermission in rolePermissions)
                {
                    rolePermission.IsDeleted = true;
                    _rolePermissionRepository.Update(rolePermission);
                }
                
                // 2. 软删除用户角色关联
                var userRoles = _userRoleRepository.GetAll("RoleId = @RoleId AND IsDeleted = false", new { RoleId = roleId });
                
                foreach (var userRole in userRoles)
                {
                    userRole.IsDeleted = true;
                    _userRoleRepository.Update(userRole);
                }
                
                // 3. 软删除角色本身
                var role = GetFirstOrDefault("Id = @Id AND IsDeleted = false", new { Id = roleId });
                if (role != null)
                {
                    role.IsDeleted = true;
                    var updateResult = Update(role);
                    tran.Complete();
                    return updateResult;
                }
                
                return 0;
            }
            catch
            {
                // 事务会自动回滚
                throw;
            }
        }

        /// <summary>
        /// 检查角色名是否已存在
        /// </summary>
        /// <param name="roleName">角色名</param>
        /// <param name="excludeId">排除的角色ID（用于更新时检查）</param>
        /// <returns>是否存在</returns>
        public bool IsRoleNameExists(string roleName, long excludeId = 0)
        {
            if (excludeId > 0)
            {
                var existingRole = GetFirstOrDefault("RoleName = @RoleName AND Id != @ExcludeId AND IsDeleted = false", 
                    new { RoleName = roleName, ExcludeId = excludeId });
                return existingRole != null;
            }
            else
            {
                var existingRole = GetFirstOrDefault("RoleName = @RoleName AND IsDeleted = false", 
                    new { RoleName = roleName });
                return existingRole != null;
            }
        }
    }
} 